package com.mqb.session;

import com.mqb.BaseMsg;
import io.netty.channel.Channel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.time.LocalDateTime;
import java.util.concurrent.ConcurrentHashMap;

/**
 *
 */
public class MsgSession {

    public final static int FINAL_STATUS = 2;
    public final static int MIDDLE_STATUS = 1;
    public final static int INITIAL_STATUS = 0;

    private static final Logger logger = LoggerFactory.getLogger(MsgSession.class);

    private static Channel serverChannel = null;

    private final static ConcurrentHashMap<String, ProcessingMsg> processingMap = new ConcurrentHashMap<>();

    public static void add(BaseMsg msg) {
        processingMap.put(msg.getId(), new ProcessingMsg(msg.getId(), INITIAL_STATUS, msg));
    }

    /**
     * 这块内容只对消息发送方进行ack确认，转发方的暂时认为不需要ack，一切以发送方认知为准
     *
     * @param msgId
     */
    public static void plus(String msgId) {
        ProcessingMsg processingMsg = processingMap.get(msgId);
        if (processingMsg == null) {
            //processingMap.put(msgId, new ProcessingMsg(msgId, INITIAL_STATUS + 1, LocalDateTime.now()));
            return;
        } else {
            if (processingMsg.status >= FINAL_STATUS) {
                processingMap.remove(msgId);
                logger.debug("消息id：[{}], 状态：[{}]，已经完成消息发送，自动从处理中的队列中移除", msgId, processingMsg.status);
                return;
            }
            processingMsg.setStatus(processingMsg.status + 1);
        }

        logger.info("消息id：[{}], 状态：[{}]", msgId, processingMsg.status);
    }

    public static void initServerChannel(Channel channel) {
        serverChannel = channel;
    }

    public static void updateStatusAfterResend(String msgId) {
        ProcessingMsg processingMsg = processingMap.get(msgId);
        if(processingMsg == null){
            return;
        }
        processingMsg.setStatus(INITIAL_STATUS);
        processingMsg.setDatetime(LocalDateTime.now());
        processingMsg.plusRetryTimes();
    }


    public static ConcurrentHashMap<String, ProcessingMsg> getProcessingMap() {
        return processingMap;
    }

    public static Channel getServerChannel() {
        return serverChannel;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class ProcessingMsg {
        private String msgId;
        private int status;
        // 消息发送时间，初始化时默认和msg内时间保持一直，后续随着重试来更新
        private LocalDateTime datetime;
        // 重试次数，设置一个上限？？
        private int retry;
        private BaseMsg msg;

        public ProcessingMsg(String msgId, int status, BaseMsg msg) {
            this.msgId = msgId;
            this.status = status;
            this.datetime = msg.getDateTime();
            this.msg = msg;
        }

        public void plusRetryTimes() {
            retry++;
        }
    }
}
